package com.shenyaocn.android.dualcamera;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.YuvImage;
import android.hardware.usb.UsbDevice;
import android.media.AudioRecord;
import android.os.Bundle;
import android.os.Handler;
import android.os.Environment;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.DeviceFilter;
import com.serenegiant.usb.IFrameCallback;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.USBMonitor.OnDeviceConnectListener;
import com.serenegiant.usb.USBMonitor.UsbControlBlock;
import com.serenegiant.usb.UVCCamera;
import com.serenegiant.widget.UVCCameraTextureView;
import com.shenyaocn.android.Encoder.AVWriter;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.shenyaocn.android.dualcamera.Helper.findAudioRecord;

public final class TakePicNow extends AppCompatActivity implements CameraDialog.CameraDialogParent {
    private static final boolean DEBUG = true;	// 用于显示调试信息
    private static final String TAG = "MainActivity";

    private AVWriter avWriterL = new AVWriter();	// 用于左边摄像头录像
    private AVWriter avWriterR = new AVWriter();	// 用于右边摄像头录像

    private AudioThread audioThread;				// 录音线程
    private AudioRecord audioRecord;
    private int bufferSize;

    private USBMonitor mUSBMonitor;					// 用于监视USB设备接入
    private UVCCamera mUVCCameraL;					// 表示左边摄像头设备
    private UVCCamera mUVCCameraR;					// 表示右边摄像头设备

    private OutputStream snapshotOutStreamL;		// 用于左边摄像头拍照
    private String snapshotFileNameL;

    private OutputStream snapshotOutStreamR;		// 用于右边摄像头拍照
    private String snapshotFileNameR;

    private static final float[] BANDWIDTH_FACTORS = { 0.5f, 0.5f };

    private int currentWidth = UVCCamera.DEFAULT_PREVIEW_WIDTH;
    private int currentHeight = UVCCamera.DEFAULT_PREVIEW_HEIGHT;

    private UVCCameraTextureView mUVCCameraViewR;	// 用于右边摄像头预览
    private Surface mRightPreviewSurface;

    private UVCCameraTextureView mUVCCameraViewL;	// 用于左边摄像头预览
    private Surface mLeftPreviewSurface;

    private ImageButton mRecordButton;
    private ImageButton mCaptureButton;
    private String tag;
    private boolean sure;
    private TextView time;
    private String times="";
    private String GPS="0-0";
    private String speed="";
    private String studentID="";
    private String teacherID="";
    private String schoolID="";
    private String carID="";
    private String gps="";
    private String type="";

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "*********onCreate");
        Intent intent = getIntent();
        studentID=intent.getStringExtra("studentid");
        schoolID = intent.getStringExtra("schoolID");
        type = intent.getStringExtra("cmd");
        teacherID = intent.getStringExtra("teacherID");
        speed = intent.getStringExtra("speed");
        carID = intent.getStringExtra("carID");
        gps = intent.getStringExtra("GPS");
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    while (count>0){
                        count--;
                        try {
                            Thread.sleep(1000);
                            handler.sendEmptyMessage(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
        Window window = getWindow();
        requestWindowFeature(Window.FEATURE_NO_TITLE);//remove title bar  即隐藏标题栏
        getSupportActionBar().hide();// 隐藏ActionBar
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//remove notification bar  即全屏
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 避免屏幕关闭
        WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();
        setContentView(R.layout.activity_main);
        com.rscja.deviceapi.OTG.getInstance().on(); //打开OTG
        mUVCCameraViewL = (UVCCameraTextureView)findViewById(R.id.camera_view_L);
        mUVCCameraViewL.setAspectRatio(width/ (float)height);

        mUVCCameraViewR = (UVCCameraTextureView)findViewById(R.id.camera_view_R);
        mUVCCameraViewR.setAspectRatio(UVCCamera.DEFAULT_PREVIEW_WIDTH / (float)UVCCamera.DEFAULT_PREVIEW_HEIGHT);

        mRecordButton = (ImageButton)findViewById(R.id.record_button);
        mRecordButton.setOnClickListener(mOnClickListener);

        mCaptureButton = (ImageButton)findViewById(R.id.capture_button);
        mCaptureButton.setOnClickListener(mOnClickListener);

        mUVCCameraViewL.setOnClickListener(mOnClickListener);
        mUVCCameraViewR.setOnClickListener(mOnClickListener);
        mCaptureButton.postDelayed(new Runnable() {
            @Override
            public void run() {
                captureSnapshot();
            }
        },4000);
        refreshControls();

        mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
        final List<DeviceFilter> filters = DeviceFilter.getDeviceFilters(this, R.xml.device_filter);
        mUSBMonitor.setDeviceFilter(filters);

    }

    @Override
    protected void onStart() {
        super.onStart();
        mUSBMonitor.register();//start
        refreshControls();

    }

    @Override
    protected void onStop() {
        mUSBMonitor.unregister();
        super.onStop();
    }

    @Override
    protected void onPause() {

        // Activity暂停时要释放左右摄像头并停止录像
        super.onPause();
    }

    // 刷新UI控件状态
    private void refreshControls() {
        try {
            boolean enabled = (mUVCCameraL != null || mUVCCameraR != null);

            findViewById(R.id.record_button).setEnabled(enabled);
            findViewById(R.id.capture_button).setEnabled(enabled);

            ((ImageButton)findViewById(R.id.record_button)).setImageResource((avWriterL.isOpened() || avWriterR.isOpened()) ? R.drawable.ic_action_record_stop : R.drawable.ic_action_record);

            findViewById(R.id.textViewUVCPromptL).setVisibility(mUVCCameraL != null ? View.GONE : View.VISIBLE);
            findViewById(R.id.textViewUVCPromptR).setVisibility(mUVCCameraR != null ? View.GONE : View.VISIBLE);

            invalidateOptionsMenu();
        } catch (Exception e){}
    }

    private synchronized void releaseCameraL() {
        synchronized (this) {
            stopRecord(avWriterL);
            if (mUVCCameraL != null) {
                try {
                    mUVCCameraL.setStatusCallback(null);
                    mUVCCameraL.setButtonCallback(null);
                    //mUVCCameraL.close();
                    mUVCCameraL.destroy();
                } catch (final Exception e) {
                    Log.e(TAG, e.getMessage());
                }
                mUVCCameraL = null;
            }

            if (mLeftPreviewSurface != null) {
                mLeftPreviewSurface.release();
                mLeftPreviewSurface = null;
            }

            findViewById(R.id.textViewUVCPromptL).setVisibility(View.VISIBLE);
        }
    }

    private synchronized void releaseCameraR() {
        synchronized (this) {
            stopRecord(avWriterR);
            if (mUVCCameraR != null) {
                try {
                    mUVCCameraR.setStatusCallback(null);
                    mUVCCameraR.setButtonCallback(null);
                    //mUVCCameraR.close();
                    mUVCCameraR.destroy();
                } catch (final Exception e) {
                    Log.e(TAG, e.getMessage());
                }
                mUVCCameraR = null;
            }

            if (mRightPreviewSurface != null) {
                mRightPreviewSurface.release();
                mRightPreviewSurface = null;
            }
            findViewById(R.id.textViewUVCPromptR).setVisibility(View.VISIBLE);
        }
    }
    private boolean isFinish=false;
    @Override
    protected void onDestroy() {




        //mUSBMonitor.unregister();

        releaseCameraL();
        releaseCameraR();
        stopAudio();

        if (mUSBMonitor != null) {
            mUSBMonitor.destroy();
            mUSBMonitor = null;
        }
        com.rscja.deviceapi.OTG.getInstance().off(); //关闭OTG
        super.onDestroy();
    }

    private void processAudio(byte[] buffer, int length) {
        if(avWriterL.isAudioEncoderOpened()) {
            avWriterL.putAudio(buffer, length);
        }

        if(avWriterR.isAudioEncoderOpened()) {
            avWriterR.putAudio(buffer, length);
        }
        // 将麦克风捕获的PCM音频数据分别发送给编码器
    }

    private class AudioThread extends Thread {
        private boolean bRun = true;
        public void run() {
            setName("AudioThread");
            byte[] buffer = new byte[bufferSize];
            try {
                while(bRun) {

                    int bufferReadResult = audioRecord.read(buffer, 0, buffer.length);
                    if(bufferReadResult <= 0) {
                        Thread.sleep(100);
                        continue;
                    }

                    processAudio(buffer, bufferReadResult);
                }
            } catch (Exception e) {
                Log.e("AudioThread", e.getMessage());
            }
        }

        public void cancel() {
            bRun = false;
        }
    }

    // 开始麦克风捕获
    private synchronized boolean startAudio() {

        if(audioRecord != null || audioThread != null) // 如果已经打开了就直接返回
            return true;

        int[] bufferSizes = new int[1];

        audioRecord = findAudioRecord(true, bufferSizes); // 参考具体函数实现
        bufferSize = bufferSizes[0];
        if (audioRecord == null) {
            return false;
        }

        audioRecord.startRecording();

        audioThread = new AudioThread();
        audioThread.start();

        return true;
    }

    private synchronized void stopAudio() {

        if (audioThread != null)
            audioThread.cancel();

        if (audioRecord != null) {
            try {
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;
            } catch (Exception e) {
            }
        }
        audioThread = null;
    }

    // 实现快照抓取
    private synchronized void captureSnapshot() {
        Log.e("MainActivity","开始准备拍照");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    Log.e("MainActivity","开始拍照");
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd.HH.mm.ss.SSSS");
                    String tm = format.format(new Date(System.currentTimeMillis()));

                    snapshotFileNameL = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DualCamera/";

                    snapshotFileNameL += studentID+""+tm;
                    snapshotFileNameL += "_L.jpg";
                    File recordFile = new File(snapshotFileNameL);	// 左边摄像头快照的文件名
                    File f = recordFile.getParentFile();
                    if (!f.exists()) {
                        f.mkdirs();
                    }
                    if(recordFile.exists()) {
                        recordFile.delete();
                    }
                    try {
                        recordFile.createNewFile();
                        snapshotOutStreamL = new FileOutputStream(recordFile);
                    } catch (Exception e){}

                    snapshotFileNameR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ShenTongPic";
                    snapshotFileNameR += studentID;
                    snapshotFileNameR += tm;
                    snapshotFileNameR += ".jpg";
                    recordFile = new File(snapshotFileNameR);		// 右边摄像头快照的文件名
                    if(recordFile.exists()) {
                        recordFile.delete();
                    }
                    try {
                        recordFile.createNewFile();
                        snapshotOutStreamR = new FileOutputStream(recordFile);
                    } catch (Exception e){}


                    Thread.sleep(2000);
                    Bitmap bitmap = BitmapFactory.decodeFile(snapshotFileNameL).copy(Bitmap.Config.ARGB_8888,true);
                    addWaterMask(bitmap);
                    try {
                        bitmap.compress(Bitmap.CompressFormat.JPEG,50,new FileOutputStream(snapshotFileNameL));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(800);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    private void addWaterMask(Bitmap bm1) {
        int height = bm1.getHeight();
        int width = bm1.getWidth();
        Paint p = new Paint();
        p.setTextSize(16);
        p.setColor(Color.RED);
        Canvas canvas = new Canvas(bm1);
        //计算文字位置 居中显示
        String text="神通测试图片";
        long l = System.currentTimeMillis();
        times = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(l));
        Paint.FontMetrics fontMetrics = p.getFontMetrics();
        float top = fontMetrics.bottom-fontMetrics.top;
        canvas.drawText("驾校编号:"+schoolID,0,top,p);
        canvas.drawText("教练员编号:"+teacherID,0,2*top,p);
        canvas.drawText("学员编号:"+studentID,0,3*top,p);
        canvas.drawText("车牌号"+carID,0,height-top,p);
        canvas.drawText("车速:"+speed+"km/h",0,height-2*top,p);
        float v = p.measureText(times);
        canvas.drawText("当前时间:"+times,width-v,height,p);
        float v1 = p.measureText(GPS);
        canvas.drawText("GPS:"+GPS,width-2*v1,height-top,p);
        canvas.save(Canvas.ALL_SAVE_FLAG);
    }
    private int count=0;
    private AlertDialog dialog;
    private void show(final String path) {
        sure=true;
        count=14;
        AlertDialog.Builder bd=new AlertDialog.Builder(this,R.style.Dialog_Fullscreen);
        View v = getLayoutInflater().inflate(R.layout.activity_show, null, false);
        Button right= (Button) v.findViewById(R.id.reload);
        LinearLayout cancle= (LinearLayout) v.findViewById(R.id.mksuer);
        time= (TextView) v.findViewById(R.id.mtimes);
        ImageView bg= (ImageView) v.findViewById(R.id.mshow_view);
        try {
            FileInputStream fis = new FileInputStream(new File(path));
            Bitmap bitmap = BitmapFactory.decodeStream(fis);
            int byteCount = bitmap.getByteCount();
            Log.e("MainActivity",byteCount+"字节数");
            bg.setImageBitmap(bitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        bd.setView(v);
        dialog = bd.create();
        dialog.show();
        Log.e("MainActivity","显示Dialog成功");
        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {

                time.setText("("+count+"s)");
            }
        });
        cancle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();

            }
        });
        right.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sure=false;
                dialog.dismiss();
            }
        });
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if (sure) {
                    Intent intent = getIntent();
                    Intent it = new Intent("com.scstjy.piccomlite");
                    it.putExtra("state","success");
                    it.putExtra("type",type);
                    it.putExtra("path",path);
                    sendBroadcast(it);
                    isFinish=true;
                    finish();
                }else {
                    captureSnapshot();
                }
            }
        });

    }
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==500) {
                if (count>0){
                    if (time!=null) {
                        time.setText("("+count+"s)");
                    }
                }else {
                    if(dialog!=null){
                        if (dialog.isShowing()) {
                            dialog.dismiss();
                        }
                    }
                }
            }else if (msg.what==800){
                Intent intent = getIntent();
                Intent it = new Intent("com.scstjy.piccomlite");
                it.putExtra("state","success");
                it.putExtra("type",type);
                it.putExtra("path",snapshotFileNameL);
                Log.e("发送广播",snapshotFileNameL);
                sendBroadcast(it);
                isFinish=true;
                finish();
            }
        }
    };
    private void openAVWriter(String fileName, AVWriter avWriter, UVCCamera uvcCamera) {
        Size size = uvcCamera.getPreviewSize();
        if(audioRecord != null) {
            avWriter.open(fileName, size.width, size.height, audioRecord.getSampleRate(), audioRecord.getChannelCount());
        } else {
            avWriter.open(fileName, size.width, size.height, 0, 0);
        }
    }

    private void startRecord(AVWriter avWriter, UVCCamera uvcCamera) {
        if(avWriter.isOpened()) {
            return;
        }

        if(uvcCamera == null) {
            return;
        }

        String extra = "L";

        if(uvcCamera == mUVCCameraR) // 通过判断是左边还是右边的摄像头来调整文件名
            extra = "R";

        String fileName = Helper.getVideoFileName(extra); // 可以参考函数实现

        openAVWriter(fileName, avWriter, uvcCamera);

        if(avWriter.isOpened()) {
            startRecTimer(); // 如果编码器打开成功，则开始录像计时
        }
    }

    // 录像计时器的实现部分
    public static String sec2time(int second){
        int h = 0;
        int d = 0;
        int s = 0;
        int temp = second%3600;
        if(second>3600){
            h= second/3600;
            if(temp!=0){
                if(temp>60){
                    d = temp/60;
                    if(temp%60!=0){
                        s = temp%60;
                    }
                }else{
                    s = temp;
                }
            }
        }else{
            d = second/60;
            if(second%60!=0){
                s = second%60;
            }
        }

        return String.format("%02d:%02d:%02d", h, d, s);
    }

    private int timer_count = 0;
    private Timer timer;

    public String getRecordTimeCount() {
        return sec2time(timer_count) + (timer_count % 2 == 0 ? " REC" : "");
    }

    private void startRecTimer() {
        stopRecTimer();
        timer_count = 0;

        timer = new Timer(true);
        timer.schedule(new TimerTask(){
            public void run() {
                timer_count++;
            }
        },1000, 1000);
    }

    private void stopRecTimer() {
        if(timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
        timer_count = 0;
    }

    private void stopRecord(AVWriter avWriter) {
        stopRecTimer();

        if(!avWriter.isOpened()) {
            return;
        }

        final String fileName = avWriter.getRecordFileName();

    }

    private final OnClickListener mOnClickListener = new OnClickListener() {
        @Override
        public void onClick(final View view) {
            switch (view.getId()) {
                case R.id.capture_button:
                    captureSnapshot();
                    break;
                case R.id.record_button:
                    if (mUVCCameraL != null) {
                        if (avWriterL.isOpened()) {
                            stopRecord(avWriterL);
                        } else {
                            startRecord(avWriterL, mUVCCameraL);
                        }
                    }

                    if (mUVCCameraR != null) {
                        if (avWriterR.isOpened()) {
                            stopRecord(avWriterR);
                        } else {
                            startRecord(avWriterR, mUVCCameraR);
                        }
                    }
                    // 实现录像功能，分别开始左右摄像头的录像

                    refreshControls();

                    break;
            }
        }
    };

    private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            if (DEBUG) Log.i(TAG, "onAttach:" + device);
            final List<UsbDevice> list = mUSBMonitor.getDeviceList();
            mUSBMonitor.requestPermission(list.get(0));

            if(list.size() > 1)
                new Handler().postDelayed(new Runnable() {public void run() {mUSBMonitor.requestPermission(list.get(1));}}, 200);
        }

        @Override
        public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) {

            if (DEBUG) Log.i(TAG, "onConnect:"+ctrlBlock.getVenderId());
            synchronized (this) {
                if (mUVCCameraL != null && mUVCCameraR != null) { // 如果左右摄像头都打开了就不能再接入设备了
                    return;
                }
                if (ctrlBlock.getVenderId() == 2){
                    if (mUVCCameraL != null && mUVCCameraL.getDevice().equals(device)){
                        return;
                    }
                } else if (ctrlBlock.getVenderId() == 3) {
                    if ((mUVCCameraR != null && mUVCCameraR.getDevice().equals(device))) {
                        return;
                    }
                }else {
                    return;
                }
                final UVCCamera camera = new UVCCamera();
                final int open_camera_nums = (mUVCCameraL != null ? 1 : 0) + (mUVCCameraR != null ? 1 : 0);
                camera.open(ctrlBlock);

                try {
                    camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.FRAME_FORMAT_MJPEG, 0.5f); // 0.5f是一个重要参数，表示带宽可以平均分配给两个摄像头，如果是一个摄像头则是1.0f，可以参考驱动实现
                } catch (final IllegalArgumentException e1) {
                    if (DEBUG) Log.i(TAG, "MJPEG Failed");
                    try {
                        camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.DEFAULT_PREVIEW_MODE, 0.5f);
                    } catch (final IllegalArgumentException e2) {
                        try {
                            currentWidth = UVCCamera.DEFAULT_PREVIEW_WIDTH;
                            currentHeight = UVCCamera.DEFAULT_PREVIEW_HEIGHT;
                            camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.DEFAULT_PREVIEW_MODE, 0.5f);
                        } catch (final IllegalArgumentException e3) {
                            camera.destroy();

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    //Toast.makeText(ShowCameraViewActivity.this, "UVC设备错误", Toast.LENGTH_LONG).show();
                                }
                            });

                            return;
                        }
                    }
                }

                // 将摄像头进行分配
                if(ctrlBlock.getVenderId() == 2 && mUVCCameraL == null) {
                    mUVCCameraL = camera;
                    if (mLeftPreviewSurface != null) {
                        mLeftPreviewSurface.release();
                        mLeftPreviewSurface = null;
                    }

                    final SurfaceTexture st = mUVCCameraViewL.getSurfaceTexture();
                    if (st != null)
                        mLeftPreviewSurface = new Surface(st);
                    mUVCCameraL.setPreviewDisplay(mLeftPreviewSurface);

                    mUVCCameraL.setFrameCallback(mUVCFrameCallbackL, UVCCamera.PIXEL_FORMAT_YUV420SP);
                    mUVCCameraL.startPreview();
                } else if(ctrlBlock.getVenderId() == 3 && mUVCCameraR == null) {
                    mUVCCameraR = camera;
                    if (mRightPreviewSurface != null) {
                        mRightPreviewSurface.release();
                        mRightPreviewSurface = null;
                    }

                    final SurfaceTexture st = mUVCCameraViewR.getSurfaceTexture();
                    if (st != null)
                        mRightPreviewSurface = new Surface(st);
                    mUVCCameraR.setPreviewDisplay(mRightPreviewSurface);

                    mUVCCameraR.setFrameCallback(mUVCFrameCallbackR, UVCCamera.PIXEL_FORMAT_YUV420SP);
                    mUVCCameraR.startPreview();

                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        refreshControls();

                        //      if (mUVCCameraL != null || mUVCCameraR != null)
                        //      startAudio();
                    }
                });
            }
        }

        @Override
        public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) {
            if (DEBUG) Log.v(TAG, "onDisconnect:" + device);
            if ((mUVCCameraL != null) && mUVCCameraL.getDevice().equals(device)) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        releaseCameraL();
                    }
                });

            } else if ((mUVCCameraR != null) && mUVCCameraR.getDevice().equals(device)) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        releaseCameraR();
                    }
                });
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    refreshControls();
                    if(mUVCCameraL == null && mUVCCameraR == null)
                        stopAudio();
                }
            });
        }

        @Override
        public void onDettach(final UsbDevice device) {
            if (DEBUG) Log.v(TAG, "onDettach:" + device);

        }

        @Override
        public void onCancel(final UsbDevice device) {
            if (DEBUG) Log.v(TAG, "onCancel:");
        }
    };

    // 左边摄像头的NV21视频帧回调
    private final IFrameCallback mUVCFrameCallbackL = new IFrameCallback() {
        @Override
        public void onFrame(final ByteBuffer frame) {

            if(mUVCCameraL == null)
                return;

            final Size size = mUVCCameraL.getPreviewSize();
            byte[] buffer = null;

            if (avWriterL.isVideoEncoderOpened()) { // 将视频帧发送到编码器
                if (buffer == null) {
                    buffer = new byte[frame.remaining()];
                    frame.get(buffer);
                }
                avWriterL.putFrame(buffer, size.width, size.height);
            }

            if(snapshotOutStreamL != null) { // 将视频帧压缩成jpeg图片，实现快照捕获
                if (buffer == null) {
                    buffer = new byte[frame.remaining()];
                    frame.get(buffer);
                }
                try {
                    new YuvImage(buffer, ImageFormat.NV21, size.width, size.height, null).compressToJpeg(new Rect(0, 0, size.width, size.height), 90, snapshotOutStreamL);
                    snapshotOutStreamL.flush();
                    snapshotOutStreamL.close();

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //Toast.makeText(ShowCameraViewActivity.this, "\"" + snapshotFileNameL + "\"", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (Exception ex) {
                } finally {
                    snapshotOutStreamL = null;
                }
            }
        }
    };

    // 参考上面的注释
    private final IFrameCallback mUVCFrameCallbackR = new IFrameCallback() {
        @Override
        public void onFrame(final ByteBuffer frame) {

            if(mUVCCameraR == null)
                return;

            final Size size = mUVCCameraR.getPreviewSize();
            byte[] buffer = null;

            if (avWriterR.isVideoEncoderOpened()) {
                if (buffer == null) {
                    buffer = new byte[frame.remaining()];
                    frame.get(buffer);
                }
                avWriterR.putFrame(buffer, size.width, size.height);
            }

            if(snapshotOutStreamR != null) {
                if (buffer == null) {
                    buffer = new byte[frame.remaining()];
                    frame.get(buffer);
                }
                try {
                    new YuvImage(buffer, ImageFormat.NV21, size.width, size.height, null).compressToJpeg(new Rect(0, 0, size.width, size.height), 90, snapshotOutStreamR);
                    snapshotOutStreamR.flush();
                    snapshotOutStreamR.close();

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //Toast.makeText(ShowCameraViewActivity.this, "\"" + snapshotFileNameR + "\"", Toast.LENGTH_SHORT).show();
                        }
                    });
                } catch (Exception ex) {
                } finally {
                    snapshotOutStreamR = null;
                }
            }
        }
    };

    /**
     * to access from CameraDialog
     * @return
     */
    @Override
    public USBMonitor getUSBMonitor() {
        return mUSBMonitor;
    }

    @Override
    public void onDialogResult(boolean canceled) {

    }
}
